﻿namespace Blaze.Security
{
    using UnityEngine;

    /// <summary>
    /// 加密管理器，统一处理加密相关逻辑。
    /// </summary>
    public class SecureManager : MonoBehaviour
    {
        /// <summary>
        /// 获取<see cref="SecureManager"/>的唯一实例。
        /// </summary>
        public static SecureManager Instance
        {
            get
            {
                if (instance == null)
                    instance = new GameObject("SecureListener").AddComponent<SecureManager>();
                return instance;
            }
        }

        /// <summary>
        /// 初始化管理器。
        /// </summary>
        public void Initialize()
        {
            SecureBool.onCheatingDetected = antiMemoryCheat;
            SecureByte.onCheatingDetected = antiMemoryCheat;
            SecureInt.onCheatingDetected = antiMemoryCheat;
            SecureFloat.onCheatingDetected = antiMemoryCheat;
            SecureDouble.onCheatingDetected = antiMemoryCheat;
            SecureVector2.onCheatingDetected = antiMemoryCheat;
            SecureVector3.onCheatingDetected = antiMemoryCheat;
            SecureString.onCheatingDetected = antiMemoryCheat;
            reinitKeys();
        }

        protected void OnApplicationFocus(bool isFocus)
        {
            if (!isFocus)
                reinitKeys();
        }

        protected void OnApplicationPause(bool isPause)
        {
            if (isPause)
                reinitKeys();
        }

        private static void antiMemoryCheat()
        {
        }

        private static void reinitKeys()
        {
            SecureBool.SetNewCryptoKey((byte) Random.Range(1, byte.MaxValue));
            SecureByte.SetNewCryptoKey((byte) Random.Range(1, byte.MaxValue));
            SecureInt.SetNewCryptoKey(Random.Range(1, int.MaxValue));
            SecureFloat.SetNewCryptoKey(Random.Range(1, int.MaxValue));
            SecureDouble.SetNewCryptoKey(Random.Range(1, int.MaxValue));
            SecureVector2.SetNewCryptoKey(Random.Range(1, int.MaxValue));
            SecureVector3.SetNewCryptoKey(Random.Range(1, int.MaxValue));
            SecureString.SetNewCryptoKey(Random.Range(1, int.MaxValue).ToString());
        }

        private static SecureManager instance;
    }
}